/**
 * ChartCellChooserFrame.java
 */
package com.pluginsacceptor.plugin.formula.MathsTrigo.support;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

import org.apache.log4j.Logger;

import com.pluginsacceptor.utils.CommunicationUtils;

/**
 * The class create frame for choice cell from spread sheet
 */
public class DataChooser extends JFrame {

    /**
	 *
	 */
	private static final long serialVersionUID = 1L;

	/** Logger */
    private static final Logger LOG = Logger.getLogger(DataChooser.class);

    /** */
    private final JTextField textField;

    /** */
    private final JButton button;

    /** */
    final MathData mathData = new MathData();

    /**
     * Constructor
     * @param chartState
     * @throws HeadlessException
     */
    public DataChooser() {
        super();
        setPreferredSize(new Dimension(300, 70));
        this.textField = new JTextField("select data");
        this.button = new JButton("ok");
        this.add(textField, BorderLayout.CENTER);
        this.add(button, BorderLayout.EAST);
        this.setTitle("Select Cells");
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.pack();
        final Rectangle parentBounds = getBounds();
        setLocation(
            (int) (parentBounds.getX() + 400),
            (int) (parentBounds.getY() + 400)
        );
        this.setAlwaysOnTop(true);
    }

    public void setButtonListener(final ActionListener actionListener) {
        this.button.addActionListener(actionListener);
    }

    /**
     * @return observer for text field changes
     */
    public Observer getObserver() {
        return new Observer() {
            @Override
            //
            public void update(final Observable o, final Object externalData) {

                if (externalData instanceof String) {
                    final String cellString = (String) externalData;

                    if (CommunicationUtils.isStartCellSelection(cellString)) {
                        textField.setText("");
                        mathData.clear();
                    } else if (CommunicationUtils.isCellData(cellString)) {
                        updateData(cellString);
                    }
                }
            }

            /**
             * Update math data
             * @param cellString the cell data
             */
            private void updateData(final String cellString) {
                try {
                    if (DataChooser.parseData(cellString, mathData)) {
                        final StringBuilder builder = new StringBuilder();
                        final List<Integer> row = mathData.getRow();
                        final List<Integer> col = mathData.getCol();
                        for (int cnt = 0; cnt < row.size(); cnt++) {
                            builder.append("[")
                            .append(CommunicationUtils.getColumnName(row.get(cnt)))
                            .append(", ").append(col.get(cnt)).append("] ");
                        }
                        textField.setText(builder.toString());
                    }
                    LOG.debug(
                        "Received data[ col: " + CommunicationUtils.getColNumFromCellString(cellString)
                            + ", row: " + CommunicationUtils.getRowNumFromCellString(cellString)
                            + ", value: " + CommunicationUtils.getValueFromCellString(cellString)
                    );
                } catch (final Exception e) {
                    LOG.warn("Unexpected message format '" + cellString + "'", e);
                }
            }
        };
    }

    /**
     * @return the mathData
     */
    public List<String> getMathData() {
        return mathData.getData();
    }

    /**
     * Parse source data string
     * @param cellString the source data string
     * @return <code>true</code> if data has been changed
     */
    public static boolean parseData(final String cellString, final MathData mathData) {
        boolean isChanged = false;
        final int col = CommunicationUtils.getColNumFromCellString(cellString);
        final int row = CommunicationUtils.getRowNumFromCellString(cellString);

        if (CommunicationUtils.isCellData(cellString)) {
            final String value = CommunicationUtils.getValueFromCellString(cellString);
//            try {
//                final Double dataItem = Double.parseDouble(value);
//                mathData.addItem(dataItem, col, row);
//                isChanged = true;
//            } catch (final Exception e) {
//                LOG.warn("invalid data value '" + value + "'");
//            }
            mathData.addItem(value, col, row);
            isChanged = true;
        }
        return isChanged;
    }
}
